package show.me.the.money.service.core;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import show.me.the.money.accredit.*;
import show.me.the.money.accredit.result.AuthorizeResult;
import show.me.the.money.config.app.Action;
import show.me.the.money.config.app.AppConfigController;
import show.me.the.money.config.app.Application;
import show.me.the.money.config.app.Module;
import show.me.the.money.util.ConfigValueParser;
import show.me.the.money.util.MD5StringUtil;
import show.me.the.money.util.context.Context;


public class Logon implements Service{
	
	private static final Log logger = LogFactory.getLog(Logon.class);
	private static int logonUserNum = 0;

	public void execute(HashMap<String,Object> req, HashMap<String,Object> res, Context ctx){
		String uid = (String)req.get("uid");
		String psw = MD5StringUtil.MD5Encode((String)req.get("psw"));
		String urole = (String)req.get("urole");
		if(!StringUtils.isEmpty(urole) && !urole.contains(",")){
			uid = uid + UsersController.SIGN + urole;
		}
		User user = UsersController.instance().getUser(uid);
		String msg = "LogonSucess";
		int code = 200;
		if(user == null){
			code = 504;
			msg = "UserNotFound";
		}
		else{
			if(user.validatePassword(psw)){
				HttpSession session = (HttpSession)ctx.get(Context.WEB_SESSION);
				session.setAttribute("uid", uid);
				logonUserNum++;
				logger.info(uid+"  logon,there almost "+logonUserNum+" people entered.");
				System.out.println("user["+uid+"] log in.");
				Object forConfig = req.get("forConfig");
				if(forConfig != null && (Boolean)forConfig){
					res.put("title", AppConfigController.instance().getTitle());
					res.put("userId", user.getId());
					res.put("userName", user.getName());
					res.put("mapSign", user.getProperty("mapSign"));
					res.put("dept", user.get("manageUnit.name"));
					res.put("deptId", user.get("manageUnit.id"));
					res.put("regionCode", user.getProperty("regionCode"));
					res.put("regionText", user.getProperty("regionCode_text"));
					res.put("jobtitle", user.get("aliesRole.name"));
					res.put("jobId", user.get("aliesRole.id"));
					
					String layoutCss = null;
					if(user.hasProperty("layoutCss")){
						layoutCss = user.getProperty("layoutCss");
					}
					else{
						List<Role> roles = user.getRoles();
						if(roles.size()>0){
							Role r = user.getRoles().get(0);
							if(r != null){
								layoutCss = r.getProperty("layoutCss");
							}
						}else{
							code = 402;
							msg = "AuthorizeFailed";
							res.put("x-response-code", code);
							res.put("x-response-msg", msg);
							return;
						}
					}
					res.put("layoutCss", layoutCss);
					Object deep = req.get("deep");
					res.put("body", getAppConf(user,deep == null || (Boolean)deep,ctx));
					
				}
			}
			else{
				code = 501;
				msg = "WrongPassword";
			}
		}
		res.put("x-response-code", code);
		res.put("x-response-msg", msg);
	}
	
	public List<HashMap<String,Object>> getAppConf(User user,boolean deep,Context ctx){
		List<HashMap<String,Object>> lsApps = new ArrayList<HashMap<String,Object>>();
		if(user != null){
			
			List<Application> apps = AppConfigController.instance().getAllApplications();
			int n = apps.size();
			for(int i = 0; i < n; i ++){
				Application app = apps.get(i);
				if(!deep){
					String appId = app.getId();
					AuthorizeResult result = user.authorize("apps",appId);
					if(result != null && result.getResult() == AuthorizeResult.NO){
						continue;
					}					
					lsApps.add(app.data());
				}
				else{
					HashMap<String,Object> j = filter(app,user,ctx);
					if(j != null){
						lsApps.add(j);
					}
				}
			}
		}
		return lsApps;
	}
	
	public static HashMap<String,Object> filter(Application app,User user,Context ctx){

		String appId = app.getId();
		AuthorizeResult result = user.authorize("apps",appId);
		if(result.getResult() == AuthorizeResult.NO){
			return null;
		}
		HashMap<String,Object> hApp = app.data();
		List<HashMap<String,Object>> lsModules = new ArrayList<HashMap<String,Object>>();
		hApp.put("modules", lsModules);
		
		List<Module> mls = app.getAllModules();
		int n1 = mls.size();		
		for(int i = 0; i < n1; i ++){
			Module module = mls.get(i);
			if(module.getType() != Module.MAIN_TYPE){
				continue;
			}
			AuthorizeResult r = user.authorize("apps",module.getFullId());
			if(r.getResult() == AuthorizeResult.NO){
				continue;
			}
			HashMap<String,Object> hMod = module.data();
			
			for(Iterator<String> it = hMod.keySet().iterator();it.hasNext();){
				String key = it.next();
				Object v = hMod.get(key);
				if(v instanceof String){
					v = ConfigValueParser.parse((String)v,ctx);
					hMod.put(key, v);
				}				
			}
			lsModules.add(hMod);
			List<HashMap<String, Object>> lsActions = new ArrayList<HashMap<String, Object>>();
			hMod.put("actions", lsActions);
			
			List<Action> als = module.getAllActions();
			int n2 = als.size();
			for(int j = 0; j < n2; j ++){
				Action action = als.get(j);
				r = user.authorize("apps",action.getFullId());
				if(r.getResult() == AuthorizeResult.NO){
					continue;
				}
				lsActions.add(action.data());
			}
		}
		return hApp;
	}
}
